import axios from 'axios'
import {AxiosResponse} from "axios"
import { ElMessage } from "element-plus"

//
import NProgress from 'nprogress';
import 'nprogress/nprogress.css'
//
import {nprogressConfig,defaultConfig,authorization,responseConfig,errorConfig} from "@/config/axios.config"

//
const {statusKey:sk,dataKey:dk,messageKey:mk,errorMsgKey:emk,statusWhiteList:swl,returnData:rd,return401:r401} = responseConfig;
const {handle:errorHandle} = errorConfig;

//
// nprogress 配置
NProgress.configure(nprogressConfig);
// axios 配置默认属性
axios.defaults = defaultConfig

//
const http = axios.create();

// 拦截 request 请求
http.interceptors.request.use((config) => {
  // 开启 ngprogress
  NProgress.start();
  // 配置 header 属性
  if(authorization.isAdd(config)){
    const d:any = authorization.header(config);
    if(config.headers){
      Object.keys(d).forEach(k => {
        config.headers[k] = d[k];
      })
    }else{
      config.headers = d;
    }
  }
  return config;
})


// 拦截 response
http.interceptors.response.use((resp:AxiosResponse) => {
  // 关闭 ngprogress
  NProgress.done();
  // 解析数据
  const data = resp.data || {}; // 数据对象
  const status = data[sk] || resp.status; // 状态码 - 约定的状态码字段
  const msg = data[mk] || resp.statusText || '';
  const emsg = data[emk] || msg;
  // const result = data[dk] || undefined
  // 自定义白名单规则
  if(swl.includes(status)) { return Promise.reject(data)}
  // 登出规则
  if(status == 401) {
    r401(resp,data)
    return Promise.reject(new Error('401'));
  }
  // 非 200 规则
  if(status != 200){
    errorHandle(data,resp,emsg,status)
    return Promise.reject(resp)
  }
  // 200
  return rd(data); // 返回数据，可以只返回 data ,也可以只返回 resp ，按照配置的规则返回
},error => {
  const status = error.response ? error.response.status : 0;
  ElMessage({
    message: error.response.data.msg || error.response.data.message, // error.response.data.msg,
    type: "error",
    duration: 3000
  });
  switch (status) {
    case 401:r401(error);break;
  }
  // 关闭 ngprogress
  NProgress.done();
  // 返回错误信息
  return Promise.reject(new Error(error))
})

//

export default http